home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmessage / xmessage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-23  |  7.7 KB  |  262 lines

  1. /*
  2.  * xmessage - utility for querying users
  3.  *
  4.  * Copyright 1988,1991 Massachusetts Institute of Technology
  5.  * Time-stamp: <91/08/27 18:33:26 gildea>
  6.  *
  7.  * Permission to use, copy, modify, and distribute this software and its
  8.  * documentation for any purpose and without fee is hereby granted, provided
  9.  * that the above copyright notice appear in all copies and that both that
  10.  * copyright notice and this permission notice appear in supporting
  11.  * documentation, and that the name of M.I.T. not be used in advertising or
  12.  * publicity pertaining to distribution of the software without specific,
  13.  * written prior permission.  M.I.T. makes no representations about the
  14.  * suitability of this software for any purpose.  It is provided "as is"
  15.  * without express or implied warranty.
  16.  *
  17.  * Originally written by Chris D. Peterson, MIT Project Athena, 1988.
  18.  * Updated by Jim Fulton, MIT X Consortium.
  19.  * Current version by Stephen Gildea <gildea@expo.lcs.mit.edu>, August 1991.
  20.  * Extensively modified by Conrad Kimball <cek@sdc.boeing.com>, Oct 1992.
  21.  */
  22.  
  23. #include <X11/Intrinsic.h>
  24. #include <X11/StringDefs.h>
  25. #include <stdio.h>
  26.  
  27. extern char *malloc();
  28.  
  29. extern char *read_file();
  30. extern Widget make_queryform();
  31.  
  32. #define    MIN_COLUMNS    1    /* min & max columns for default geometry */
  33. #define    MAX_COLUMNS    80
  34.  
  35. #define    MIN_LINES    1    /* min & max lines for default geometry */
  36. #define    MAX_LINES    20
  37.  
  38. /*
  39.  * data used by xmessage
  40.  */
  41.  
  42. char *ProgramName;
  43.  
  44. static Atom wm_delete_window;
  45.  
  46. static struct _MessageResources {
  47.     char *file;
  48.     char *button_list;
  49.     char *default_button;
  50.     Boolean print_value;
  51.     char *warp_button;
  52.     int columns;
  53.     int min_columns;
  54.     int max_columns;
  55.     int lines;
  56.     int min_lines;
  57.     int max_lines;
  58.     char *message;
  59. } qres;                /* initialized by resources below */
  60.  
  61. #define offset(field) XtOffsetOf(struct _MessageResources, field)
  62. static XtResource resources[] = {
  63.     { "message", "Message", XtRString, sizeof (char *), 
  64.       offset(message), XtRString, (XtPointer) NULL },
  65.     { "file", "File", XtRString, sizeof (char *), 
  66.       offset(file), XtRString, (XtPointer) NULL },
  67.     { "buttons", "Buttons", XtRString, sizeof (char *),
  68.       offset(button_list), XtRString, (XtPointer) "okay:0" },
  69.     { "defaultButton", "DefaultButton", XtRString, sizeof (char *),
  70.       offset(default_button), XtRString, (XtPointer) NULL },
  71.     { "printValue", "PrintValue", XtRBoolean, sizeof (Boolean),
  72.       offset(print_value), XtRString, "false" },
  73.     { "warpButton", "WarpButton", XtRString, sizeof (char *),
  74.       offset(warp_button), XtRString, (XtPointer) NULL },
  75.     { "columns", "Columns", XtRInt, sizeof (int),
  76.       offset(columns), XtRImmediate, 0 },
  77.     { "minColumns", "MinColumns", XtRInt, sizeof (int),
  78.       offset(min_columns), XtRImmediate, (XtPointer) MIN_COLUMNS },
  79.     { "maxColumns", "MaxColumns", XtRInt, sizeof (int),
  80.       offset(max_columns), XtRImmediate, (XtPointer) MAX_COLUMNS },
  81.     { "lines", "Lines", XtRInt, sizeof (int),
  82.       offset(lines), XtRImmediate, 0 },
  83.     { "minLines", "MinLines", XtRInt, sizeof (int),
  84.       offset(min_lines), XtRImmediate, (XtPointer) MIN_LINES },
  85.     { "maxLines", "MaxLines", XtRInt, sizeof (int),
  86.       offset(max_lines), XtRImmediate, (XtPointer) MAX_LINES },
  87. };
  88. #undef offset
  89.  
  90. static XrmOptionDescRec optionList[] =  {
  91.     { "-file",    ".file", XrmoptionSepArg, (XPointer) NULL },
  92.     { "-buttons", ".buttons", XrmoptionSepArg, (XPointer) NULL },
  93.     { "-default", ".defaultButton", XrmoptionSepArg, (XPointer) NULL },
  94.     { "-print",   ".printValue", XrmoptionNoArg, (XPointer) "on" },
  95.     { "-warp",    ".warpButton", XrmoptionSepArg, (XPointer) NULL },
  96.     { "-columns", ".columns", XrmoptionSepArg, (XPointer) NULL },
  97.     { "-lines",   ".lines", XrmoptionSepArg, (XPointer) NULL },
  98. };
  99.  
  100. static String fallback_resources[] = {
  101.     "*baseTranslations: #override :<Key>Return: default-exit()",
  102.     NULL};
  103.  
  104.  
  105. /*
  106.  * usage
  107.  */
  108.  
  109. static void usage ()
  110. {
  111.     static char *options[] = {
  112. "    -file filename              file to read message from, - means stdin",
  113. "    -buttons string             comma-separated list of label:exitcode",
  114. "    -default button             button to activate if Return is pressed",
  115. "    -warp button                button to warp cursor to when exposed",
  116. "    -print                      print the button label when selected",
  117. "    -columns n                  size window to hold n columsn",
  118. "    -lines n                    size window to hold n lines",
  119. "",
  120. NULL};
  121.     char **cpp;
  122.  
  123.     fprintf (stderr, "usage: %s [-options] [message ...]\n\n",
  124.          ProgramName);
  125.     fprintf (stderr, "where options include:\n");
  126.     for (cpp = options; *cpp; cpp++) {
  127.     fprintf (stderr, "%s\n", *cpp);
  128.     }
  129.     exit (1);
  130.     /* NOTREACHED */
  131. }
  132.  
  133. /*
  134.  * Action to implement ICCCM delete_window and other translations.
  135.  * Takes one argument, the exit status.
  136.  */
  137. /* ARGSUSED */
  138. static void
  139. exit_action(w, event, params, num_params)
  140.     Widget w;            /* unused */
  141.     XEvent *event;
  142.     String *params;
  143.     Cardinal *num_params;
  144. {
  145.     int exit_status = 0;
  146.  
  147.     if(event->type == ClientMessage
  148.        && event->xclient.data.l[0] != wm_delete_window)
  149.     return;
  150.     
  151.     if (*num_params == 1)
  152.     exit_status = atoi(params[0]);
  153.     exit(exit_status);
  154. }
  155.  
  156. Widget default_button_widget = NULL;
  157.  
  158. /* ARGSUSED */
  159. static void
  160. default_exit_action(w, event, params, num_params)
  161.     Widget w;
  162.     XEvent *event;
  163.     String *params;
  164.     Cardinal *num_params;
  165. {
  166.     if (default_button_widget != NULL)
  167.     XtCallCallbacks(default_button_widget, XtNcallback, NULL);
  168. }
  169.  
  170. XtActionsRec actions_list[] = {
  171.     "exit", exit_action,
  172.     "default-exit", default_exit_action,
  173. };
  174.  
  175. static String top_trans =
  176.     "<ClientMessage>WM_PROTOCOLS: exit(1)\n";
  177.  
  178. /*
  179.  * xmessage main program - make sure that there is a message, then create
  180.  * the query box and go.  Callbacks take care of exiting.
  181.  */
  182. main (argc, argv)
  183.     int argc;
  184.     char **argv;
  185. {
  186.     Widget top, queryform;
  187.     XtAppContext app_con;
  188.  
  189.     ProgramName = argv[0];
  190.  
  191.     top = XtAppInitialize (&app_con, "Xmessage",
  192.                optionList, XtNumber(optionList), &argc, argv,
  193.                fallback_resources, NULL, 0);
  194.  
  195.     XtGetApplicationResources (top, (XtPointer) &qres, resources,
  196.                    XtNumber(resources), NULL, 0);
  197.  
  198.     if (argc > 1 && !strcmp(argv[1], "-help")) {
  199.     usage();
  200.     }
  201.  
  202.     if (argc > 1 && qres.file == NULL) {
  203.     int i, len;
  204.     char *cp;
  205.  
  206.     len = argc - 1;        /* spaces between words and final NULL */
  207.     for (i=1; i<argc; i++)
  208.         len += strlen(argv[i]);
  209.     qres.message = malloc(len);
  210.     if (!qres.message)
  211.         perror("string malloc");
  212.     cp = qres.message;
  213.     for (i=1; i<argc; i++) {
  214.         strcpy(cp, argv[i]);
  215.         cp += strlen(argv[i]);
  216.         if (i != argc-1)
  217.         *cp++ = ' ';
  218.         else
  219.         *cp = '\0';
  220.     }
  221.     } else if (argc > 1 || qres.file == NULL) {
  222.     usage ();
  223.     }
  224.  
  225.     /* make sure there is some message or file to display */
  226.     if (qres.message == NULL && qres.file == NULL) {
  227.     fprintf (stderr, "%s: no message\n", ProgramName);
  228.     exit (1);
  229.     }
  230.  
  231.     XtAppAddActions(app_con, actions_list, XtNumber(actions_list));
  232.     XtOverrideTranslations(top, XtParseTranslationTable(top_trans));
  233.  
  234.     /*
  235.      * create the query form; this is where most of the real work is done
  236.      */
  237.     queryform = make_queryform (top, qres.message, qres.file, qres.button_list,
  238.                 qres.print_value, qres.default_button,
  239.                 qres.warp_button,
  240.                 qres.columns, qres.min_columns,
  241.                 qres.max_columns,
  242.                 qres.lines, qres.min_lines, qres.max_lines);
  243.     if (!queryform) {
  244.     fprintf (stderr,
  245.          "%s: unable to create query form with buttons: %s\n",
  246.          ProgramName, qres.button_list);
  247.     exit (1);
  248.     }
  249.  
  250.     XtSetMappedWhenManaged(top, FALSE);
  251.     XtRealizeWidget(top);
  252.  
  253.     /* do WM_DELETE_WINDOW before map */
  254.     wm_delete_window = XInternAtom(XtDisplay(top), "WM_DELETE_WINDOW", False);
  255.     XSetWMProtocols(XtDisplay(top), XtWindow(top), &wm_delete_window, 1);
  256.  
  257.     XtMapWidget(top);
  258.     XtAppMainLoop(app_con);
  259.  
  260.     exit (0);
  261. }
  262.